import http from "@/util/http";
class Log {
	static console = true;
	log(title, text) {
		if (!Log.console) return;
		if (import.meta.env.MODE === 'production') return;
		const color = '#ff4d4f';
		console.log(
			`%c ${title} %c ${text} %c`,
			`background:${color};border:1px solid ${color}; padding: 1px; border-radius: 2px 0 0 2px; color: #fff;`,
			`border:1px solid ${color}; padding: 1px; border-radius: 0 2px 2px 0; color: ${color};`,
			'background:transparent'
		);
	}
	closeConsole() {
		Log.console = false;
	}
}
class EventDispatcher extends Log {
	listeners = {};

	addEventListener(type, listener) {
		if (!this.listeners[type]) {
			this.listeners[type] = [];
		}
		if (this.listeners[type].indexOf(listener) === -1) {
			this.listeners[type].push(listener);
		}
	}

	removeEventListener(type) {
		this.listeners[type] = [];
	}

	dispatchEvent(type, data) {
		const listenerArray = this.listeners[type] || [];
		if (listenerArray.length === 0) return;
		listenerArray.forEach(listener => {
			listener.call(this, data);
		});
	}
}

export class WebSocketClient extends EventDispatcher {
	// #socket链接
	url = '';
	// #socket实例
	socket = null;
	// #重连次数
	reconnectAttempts = 0;
	// #最大重连数
	maxReconnectAttempts = 6*5;//5 mins
	recLogAttempts = 0;
	maxLogAttempts = 8;
	// #重连间隔
	reconnectInterval = 1000 * 10; // 10 seconds
	// #发送心跳数据间隔
	heartbeatInterval = 1000 * 5;
	// #计时器id
	heartbeatTimer = undefined;
	reconnectTimer = undefined;
	// #彻底终止ws
	stopWs = false;
	// *构造函数
	constructor(url) {
		super();
		this.url = url;
	}
	// >生命周期钩子
	onopen(callBack) {
		this.addEventListener('open', callBack);
	}
	onmessage(callBack) {
		this.addEventListener('message', callBack);
	}
	onclose(callBack) {
		this.addEventListener('close', callBack);
	}
	onerror(callBack) {
		this.addEventListener('error', callBack);
	}
	// >消息发送
	send(message) {
		if (this.socket) {
			this.socket.send(message);
		} else {
			console.error('[WebSocket] 未连接');
		}
	}
	
	setUrl(url) {
		this.url = url;
	}

	// !初始化连接
	connect() {
		let that = this
		if (this.reconnectAttempts === 0) {
			this.log('WebSocket', `初始化连接中... ${this.url}`);
		}
		const wsUri = this.url;
		try {
			// console.log('this.socket=',this.socket)
			//先关闭之前的连接，进行新的连接
			if(this.socket) {
			uni.closeSocket()
			}
			let socket1 = uni.connectSocket({
				url: this.url,
				success(res) {
					console.log('success=', res)
					//打开连接
					uni.onSocketOpen(function(res) {
						console.log('WebSocket连接已打开！', res);
						that.stopWs = false;
						// 重置重连尝试成功连接
						that.reconnectAttempts = 0;
						//清空之前的重连任务
						if(that.reconnectTimer) {
							that.closeReconnectTimer();
						}
						// 在连接成功时停止当前的心跳检测并重新启动
						that.startHeartbeat();
						that.dispatchEvent('open', res);
					});
				},
				fail(res) {
					console.log('fail=', res)
				}
			});
			this.socket = socket1
			console.log('socket1=', socket1)

			//接收消息
			uni.onSocketMessage(function(res) {
				if(that.recLogAttempts<that.maxLogAttempts){
					that.recLogAttempts++
					console.log('接受 WebSocket 消息！', res.data);
				}
				that.dispatchEvent('message', res.data);
				that.startHeartbeat();
			});
			//监听 WebSocket 关闭
			uni.onSocketClose(function(res) {
				console.log('监听 WebSocket 关闭', res);
				if (that.reconnectAttempts === 0) {
					that.log('WebSocket', `连接断开[onclose]...    ${that.url}`);
				}
				if (!that.stopWs) {
					that.handleReconnect();
				}
				that.dispatchEvent('close', res);
			});
			//连接发生错误
			uni.onSocketError(function(res) {
				console.log('监听 WebSocket 错误，重新发起连接', res);
				that.dispatchEvent('error', res);
				let token = uni.getStorageSync('tokenValue')
				let userInfo = uni.getStorageSync('userInfo')
				if (token && userInfo) {
					let url = `${http.baseWebsocketUrl}${userInfo.id}?satoken=${token}&terminalType=2&loginType=user&productId=13`
					that.setUrl(url)
				}
				// uni.showToast({
				// 	title:'重连'+JSON.stringify(res),
				// 	icon:'none'
				// })
				if (!that.stopWs) {
					that.handleReconnect();
				}
			});
		} catch (e) {
			//TODO handle the exception
		}
	}

	// > 断网重连逻辑
	handleReconnect() {
		if (this.reconnectAttempts < this.maxReconnectAttempts) {
			this.reconnectAttempts++;
			this.log('WebSocket', `尝试重连... (${this.reconnectAttempts}/${this.maxReconnectAttempts})       ${this.url}`);
			//清空之前的重连任务
			if(this.reconnectTimer) {
				this.closeReconnectTimer();
			}
			this.reconnectTimer=setTimeout(() => {
				this.connect();
			}, this.reconnectInterval);
		} else {
			this.closeHeartbeat();
			this.log('WebSocket', `最大重连失败，终止重连: ${this.url}`);
		}
	}

	// >关闭连接
	close() {
		if (this.socket) {
			this.stopWs = true;
			uni.closeSocket();
			this.socket = null;
			this.removeEventListener('open');
			this.removeEventListener('message');
			this.removeEventListener('close');
			this.removeEventListener('error');
		}
		this.closeHeartbeat();
	}

	// >开始心跳检测 -> 定时发送心跳消息
	startHeartbeat() {
		if (this.stopWs) return;
		if (this.heartbeatTimer) {
			this.closeHeartbeat();
		}
		this.heartbeatTimer = setInterval(() => {
			let message = "ping"
			uni.sendSocketMessage({
				data: message
			})
			// this.log('WebSocket', '送心跳数据...'+message);
		}, this.heartbeatInterval);
	}

	// >关闭心跳
	closeHeartbeat() {
		clearInterval(this.heartbeatTimer);
		this.heartbeatTimer = undefined;
	}
	// >关闭重连
	closeReconnectTimer() {
		clearTimeout(this.reconnectTimer);
		this.reconnectTimer = undefined;
	}
}